package application.controllers;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Set;

import javax.swing.table.DefaultTableModel;

import application.models.datalayer.Date;
import application.models.exceptions.InvalidAttributeException;
import application.models.models.ReservationModel;

/**
 * This controller is responsible for the behavior of the MainView.
 * 
 * @author Morten Therkildsen & Philip Rasmussen
 */
public class MainViewController {

	private ReservationModel selected;
	
	/**
	 * This method gets the reservation that is selected in the reservation bar graph
	 * 
	 * @return the selected reservationModel
	 */
	public ReservationModel getSelection(){
			
		return selected;
	}
	
	/**
	 * This method sets the selected reservation in the reservation bar graph
	 * 
	 * @return the selected reservationModel
	 */
	public void setSelection(ReservationModel model){
		
		selected = model;
	}
	
	public void drawReservationGraph(Set<ReservationModel> reservations, ReservationModel selected, Date from, Date to, Graphics g){
		
		Rectangle bounds = g.getClipBounds();
		double height = bounds.getHeight()+1;
		double width = bounds.getWidth();
		
		final int msPerDay = 1000*60*60*24;
		
		long daysToRender = (to.getTime()-from.getTime())/msPerDay;
		double widthPerDay = width/daysToRender;
		
		for(ReservationModel model : reservations){
			
			try{

				if(model.equals(selected)) g.setColor(Color.RED);
				else g.setColor(Color.BLUE);
				
				Date starts = (Date) model.getAttribute("starts");
				Date ends = (Date) model.getAttribute("ends");
				
				if(starts == null || ends == null) continue;

				// Set reservation periods starting or ending out of the drawable period to the boundary of the drawable period
				starts = starts.getTime() < from.getTime() ? from : starts;
				ends = ends.getTime() > to.getTime() ? to : ends;

				int startDayFromPeriodStart = (int) ((starts.getTime()-from.getTime())/msPerDay);
				int reservationPeriodInDays = (int) ((ends.getTime()-starts.getTime())/msPerDay);

				// Block
				g.fillRect((int) (widthPerDay*startDayFromPeriodStart), -1, (int) (widthPerDay*reservationPeriodInDays), (int) height);
				
				// Limiters
				g.setColor(Color.GRAY);
				g.drawRect((int) (widthPerDay*startDayFromPeriodStart), -1, (int) (widthPerDay*reservationPeriodInDays), (int) height);

			} catch(InvalidAttributeException e){/*IGNORE*/}
		}
		
		// Draw day limiters
		
		g.setColor(Color.BLACK);
		for(int i = 1; i*widthPerDay <= width; ++i){
			
			int x = (int) (i*widthPerDay);
			g.drawLine(x, 0, x, (int) height);
		}
	}
	
	public ReservationModel getClickedReservation(ReservationModel[] reservations, int x, int y, int height, int width, Date from, Date to){
		
		final int msPerDay = 1000*60*60*24;
		
		long daysToRender = (to.getTime()-from.getTime())/msPerDay;
		double widthPerDay = width/daysToRender;
		
		for(ReservationModel model : reservations){
			
			try{
				
				Date starts = (Date) model.getAttribute("starts");
				Date ends = (Date) model.getAttribute("ends");
				
				if(starts == null || ends == null) continue;

				// Set reservation periods starting or ending out of the drawable period to the boundary of the drawable period
				starts = starts.getTime() < from.getTime() ? from : starts;
				ends = ends.getTime() > to.getTime() ? to : ends;

				int startDayFromPeroidStart = (int) ((starts.getTime()-from.getTime())/msPerDay);
				int reservationPeriodInDays = (int) ((ends.getTime()-starts.getTime())/msPerDay);
				
				if((int) (widthPerDay*startDayFromPeroidStart) < x && x < (int) (widthPerDay*(startDayFromPeroidStart+reservationPeriodInDays))) return model;

			} catch(InvalidAttributeException e){/*IGNORE*/}
		}
		
		return null;
	}
}
